/******************************************
Probando_Dijkstra.java
Universidad del Valle de Guatemala
Algoritmos y Estructura de Datos
Autor:
    Martín Guzmán
Fecha: 8 de Noviembre de 2009
Descripción: Uso del algoritmo de Dijkstra para
 * hallar la ruta más corta entre 2 nodos de
 * un grafo
*******************************************/

import java.lang.reflect.Array;
import java.util.Scanner;

import java.util.LinkedList;
import java.util.Random;

public class Probando_Dijkstra {
    private static int hacer;
    private static int opciones_del_menu = 0;

    private static Scanner scan = new Scanner(System.in);

    //***********************
    private static Grafo<String> graph;
    //***********************
    

    //método main donde empieza la ejecución del programa
    public static void main(String args[])
    {
        System.out.println("\n********************************************************\n");
        System.out.println("     Bienvenido al sistema grafo\n");
        System.out.println("*********************************************************");

        Probando_Dijkstra.graph = new Grafo<String>();
        
        //ciclo para repetir hasta que quiera salir del programa
        do
        {
            Menu();
        } while (hacer!=opciones_del_menu);//hasta que precione salir
        System.out.println("\n\n¡Gracias por utilizar el programa!");
    }

    //método que despliega el menú para realizar la acción del usuario ****************************
    public static void Menu(){
        do //ciclo hasta que ingrese bien una acción a realizar
        {
            opciones_del_menu=0;

            System.out.println("\n\t************* Menu Principal del grafo *************\n");
            System.out.println("1- Agragar nodo");
            opciones_del_menu++;
            System.out.println("2- Agregar enlace");
            opciones_del_menu++;
            System.out.println("3- Quitar nodo");
            opciones_del_menu++;
            System.out.println("4- Quitar enlace");
            opciones_del_menu++;
            System.out.println("5- Encontrar ruta más corta entre 2 nodos (usando Dijkstra)");
            opciones_del_menu++;
            System.out.println("6- Salir del Programa");
            opciones_del_menu++;
            System.out.print("\t¿Qué desea hacer?\tMarque el número: ");
            //despliega mensaje de error si no escoje una opcion del menu principal
            try{
                hacer=scan.nextInt();
            }
            catch(Exception exp){ //para prevenir el ingreso de algún caracter diferente a número
                System.out.println("¡Error accion no válida!\n");
                hacer=-1;
            }
            scan.nextLine();
            if ((hacer<1 || hacer>opciones_del_menu) &&(hacer!=-1))
                System.out.println("¡Error accion fuera de las opciones!\n");

        } while (hacer<1 || hacer>opciones_del_menu);
        System.out.println("\n*************************************************************\n");


        //para realizar la accion marcada arriba
        switch (hacer)
        {
            case 1://  ********* 1- Agregar nodo ******************************************************
                //agregar nodo
                //System.out.println("Agregando nodo:");
                System.out.println("Ingrese el nombre del nodo que desea agregar:");
                String temp = scan.nextLine();

                graph.Agregar_nodo(temp);

                System.out.println("Grafo:\n"+graph.toString());//TEMPORAL

                break;
            case 2://  ********* 2- Agregar enlace ****************************************************
                //agregar enlace
                //System.out.println("Agregar enlace:");
                System.out.println("Para agregar un enlace siga la siguiente sintaxis:");
                System.out.println("Si quiere agregar un enlace del nodo A al nodo B y de peso NUM: A,B,NUM");
                String temp2 = scan.nextLine();
                
                String[] arreglo_temp = temp2.split(",");
                if(arreglo_temp.length!=3){
                    System.out.println(" >> Lo siento, ingresó mal la cantidad de parámetros.");
                    break;
                }
                String A = arreglo_temp[0];
                String B = arreglo_temp[1];
                int peso;
                try{
                    peso=Integer.parseInt(arreglo_temp[2]);
                }catch(Exception exp){
                    System.out.println(" >> Lo siento, ingresó un valor no numérico como peso.");
                    break;
                }

                graph.Agregar_enlace(A, B, peso);

                System.out.println("Grafo:\n"+graph.toString());//TEMPORAL

                break;
            case 3://  ********* 3- Quitar nodo *******************************************************
                //quitar nodo
                System.out.println("Ingrese el nombre del nodo que desea quitar:");
                String temp3 = scan.nextLine();

                if(graph.getAdjacency_map().contains(temp3)){
                    int num_temp = graph.getAdjacency_map().indexOf(temp3);
                    graph.getAdjacency_map().remove(num_temp);
                    graph.edges_list.remove(num_temp);
                    
                    // quitar todos los enlaces que tenía ese nodo *****************
                    for(int i=0;i<graph.adjacency_map.size();i++){
                        for(int j=0;j<graph.edges_list.get(i).size();j++){
                            if(graph.edges_list.get(i).get(j).getNombre().compareToIgnoreCase(temp3)==0){
                                graph.edges_list.get(i).remove(j);
                            }
                        }
                    }
                    //**************************************************************

                    System.out.println("Grafo:\n"+graph.toString());//TEMPORAL
                    
                }
                else{
                    System.out.println(" >> El nodo que está tratando de quitar no existe");
                }


                break;
            case 4://  ********* 4- Quitar enlace *****************************************************
                //quitar enlace
                System.out.println("Para quitar un enlace siga la siguiente sintaxis:");
                System.out.println("Si quiere quitar el enlace del nodo A al nodo B: A,B");
                String temp4 = scan.nextLine();

                String[] arreglo_2 = temp4.split(",");
                if (arreglo_2.length!=2){
                    System.out.println(" >> Lo siento, número incorrecto de parámetros");
                }
                else{
                    if(graph.adjacency_map.contains(arreglo_2[0])){
                        int len_1 = graph.edges_list.get(graph.adjacency_map.indexOf(arreglo_2[0])).size();
                        for(int i=0;i<graph.edges_list.get(graph.adjacency_map.indexOf(arreglo_2[0])).size();i++){
                            if(graph.edges_list.get(graph.adjacency_map.indexOf(arreglo_2[0])).get(i).getNombre().compareTo(arreglo_2[1])==0){
                                graph.edges_list.get(graph.adjacency_map.indexOf(arreglo_2[0])).remove(i);
                            }
                        }
                        if (len_1==graph.edges_list.get(graph.adjacency_map.indexOf(arreglo_2[0])).size()){
                            System.out.println(" >> Lo siento, el segundo nodo no existe");
                        }

                    }else{
                        System.out.println(" >> Lo siento, el primer nodo no existe");
                    }
                }

                System.out.println("Grafo:\n"+graph.toString());//TEMPORAL

                break;
            case 5://  ********* 5- Encontrar ruta más corta entre 2 nodos (usando Dijkstra) **********
                //ruta más corta
                if(graph.adjacency_map.size()==0){
                    System.out.println(" >> Lo siento, el grafo esta vacío, primero debe definirlo");
                    break;
                }
                //----------------------------
                System.out.println("Ingrese el nodo inicial: ");
                String nodo_inicial = scan.nextLine();
                if(graph.adjacency_map.contains(nodo_inicial)==false){
                    System.out.println(" >> Lo siento, el grafo no contiene a ese nodo");
                }
                
                String var=graph.adjacency_map.get(graph.adjacency_map.indexOf(nodo_inicial));
                System.out.println("\n********************************************************\nRutas mas cortas desde el nodo: "+var+" hasta:\n"+graph.Algoritmo_Dijkstra(nodo_inicial));

                //----------------------------

                break;
        }
    }
}

